import hashlib
import logging
import random
import uuid

from flask import Blueprint, jsonify, session, g
from flask_restful import Api, Resource, reqparse, inputs, fields, marshal_with, marshal

from apps.models.user_model import User
from apps.util import login_required
from exts import db, cache

user_bp = Blueprint('user', __name__)
api = Api(user_bp)

logger = logging.getLogger(__name__)  # 10.日志
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)


user_fields = {
    'id': fields.Integer,
    'username': fields.String,
    'phone': fields.String,
    'icon': fields.String,
}
# 3.过度的数据暴露

class loginapi(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str)
        parser.add_argument('password', type=str)
        args = parser.parse_args()
        username = str(args['username'])
        password = str(args['password'])
        new_password = hashlib.sha256(password.encode('utf-8')).hexdigest()  #哈希加密 2.失效的用户身份验证
        user = User.query.filter_by(username=username).first()
        if user.password == new_password:
            # 记录登录状态
            # token 存储用户登录信息
            token = str(uuid.uuid4()).replace('-', '')+str(random.randint(100, 999))
            cache.set(token, username)  # token+唯一标识
            logger.info('用户登录成功')
            return {'status': 200, 'msg': '用户登录成功', 'token': token}  # token给前端
        else:
            logger.error('用户登录失败')
            return {'status': 400, 'msg': '用户名或密码错误'}


class registerapi(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str)
        parser.add_argument('password', type=str)
        parser.add_argument('repassword', type=str)
        parser.add_argument('phone', type=str)
        args = parser.parse_args()
        username = str(args['username'])
        password = str(args['password'])
        repassword = str(args['repassword'])
        phone = str(args['phone'])
        users = User.query.all()
        for new_user in users:
            if new_user.phone == phone:
                logger.error('此号码已被注册')
                return jsonify(code=400, msg='此号码已被注册')
            else:
                pass
            if new_user.username == username:
                return jsonify(code=400, msg='此用户名已被注册')
            else:
                pass
        if password == repassword:
            if len(phone) > 11 or len(phone) == 0:
                return jsonify(code=400, msg='电话格式不合适')
            else:
                # 添加
                user = User()
                user.username = username
                user.password = hashlib.sha256(password.encode('utf-8')).hexdigest()  # 加密
                user.phone = phone
                db.session.add(user)
                db.session.commit()
                logger.info('新用户注册成功')
                return {'status': 200, 'msg': '用户注册成功'}
        else:
            logger.error('新用户注册失败')
            return {'status': 400, 'errmsg': '密码不一致'}

# 获取图像生成的随机验证码
class ForgetPasswordApi(Resource):
    def get(self):
        s = 'qwerrtyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'
        code = ''
        for i in range(4):
            ran = random.choice(s)
            code+= ran
        # 保存code
        session['code'] = code  # 拿到验证码，前端绘制
        return {'code': code}


# 获取用户信息 无漏洞查找id 1.失效的对象级授权
class GetInformation_newApi(Resource):
    @login_required
    def get(self):
        user_id = g.user.id
        user = User.query.get(user_id)
        return marshal(user, user_fields)


# 修改密码
# 6. 无批量分配漏洞
class updatepassword_newApi(Resource):
    @login_required
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('password', type=str)
        parser.add_argument('newpassword', type=str)
        args = parser.parse_args()
        username = g.user.username
        password = args.get('password')
        new_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
        newpassword = args.get('newpassword')
        real_password = hashlib.sha256(newpassword.encode('utf-8')).hexdigest()
        user = User.query.filter_by(username=username).first()
        # code 400不可用 200可用
        if user.password == new_password:
            user.password = real_password
            db.session.commit()
            return jsonify(code=200, msg='密码修改成功！')
        else:
            return jsonify(code=400, msg='旧密码错误！')


api.add_resource(loginapi, '/login')
api.add_resource(registerapi, '/register')
api.add_resource(ForgetPasswordApi, '/forget')
api.add_resource(GetInformation_newApi, '/get_information')
api.add_resource(updatepassword_newApi, '/update_password')

